import 'dart:convert';

import 'package:shared_preferences/shared_preferences.dart';

/// Created by XieXin on 2020/3/19.
/// SharedPreferences 工具类
class SPUtils {
  static SharedPreferences? _sp;

  ///初始化 SPUtils 启动时调用
  static Future<void> init() async {
    // 保持本地实例直到完全初始化。
    await _init();
  }

  ///初始化SharedPreferences
  static Future<SharedPreferences> _init() async {
    _sp = await SharedPreferences.getInstance();
    return _sp!;
  }

  ///保存对象
  static Future<bool> putObject(String key, Object? value) {
    if (_sp == null) return Future.value(false);
    return _sp!.setString(key, value == null ? "" : json.encode(value));
  }

  ///获取对象
  static T getObj<T>(String key, T Function(Map v) f, T defValue) {
    Map? map = getObject(key);
    return map == null ? defValue : f(map);
  }

  ///获取对象
  static Map? getObject(String key) {
    if (_sp == null) return null;
    String? data = _sp!.getString(key);
    return (data == null || data.isEmpty) ? null : json.decode(data);
  }

  ///保存列表
  static Future<bool> putObjectList(String key, List<Object> list) {
    if (_sp == null) return Future.value(false);
    List<String> dataList = list.map((value) {
      return json.encode(value);
    }).toList();
    return _sp!.setStringList(key, dataList);
  }

  ///获取列表
  static List<T> getObjList<T>(String key, T Function(Map v) f,
      {List<T> defValue = const []}) {
    List<Map>? dataList = getObjectList(key);
    List<T>? list = dataList?.map((value) {
      return f(value);
    }).toList();
    return list ?? defValue;
  }

  ///获取列表
  static List<Map>? getObjectList(String key) {
    if (_sp == null) return null;
    List<String>? dataLis = _sp!.getStringList(key);
    return dataLis?.map((value) {
      Map dataMap = json.decode(value);
      return dataMap;
    }).toList();
  }

  ///获取字符串
  static String getString(String key, {String defValue = ''}) {
    if (_sp == null) return "";
    return _sp!.getString(key) ?? defValue;
  }

  ///保存字符串
  static Future<bool> putString(String key, String value) {
    if (_sp == null) return Future.value(false);
    return _sp!.setString(key, value);
  }

  ///获取布尔类型
  static bool getBool(String key, {bool defValue = false}) {
    if (_sp == null) return defValue;
    return _sp!.getBool(key) ?? defValue;
  }

  ///保存类型
  static Future<bool> putBool(String key, bool value) {
    if (_sp == null) return Future.value(false);
    return _sp!.setBool(key, value);
  }

  ///获取整型
  static int getInt(String key, {int defValue = 0}) {
    if (_sp == null) return defValue;
    return _sp!.getInt(key) ?? defValue;
  }

  ///保存整型
  static Future<bool> putInt(String key, int value) {
    if (_sp == null) return Future.value(false);
    return _sp!.setInt(key, value);
  }

  ///获取Double类型
  static double getDouble(String key, {double defValue = 0.0}) {
    if (_sp == null) return defValue;
    return _sp!.getDouble(key) ?? defValue;
  }

  ///保存Double类型
  static Future<bool> putDouble(String key, double value) {
    if (_sp == null) return Future.value(false);
    return _sp!.setDouble(key, value);
  }

  ///获取字符串列表
  static List<String> getStringList(String key,
      {List<String> defValue = const []}) {
    if (_sp == null) return defValue;
    return _sp!.getStringList(key) ?? defValue;
  }

  ///保存字符串列表
  static Future<bool> putStringList(String key, List<String> value) {
    if (_sp == null) return Future.value(false);
    return _sp!.setStringList(key, value);
  }

  ///获取dynamic.
  static dynamic getDynamic(String key, Object defValue) {
    if (_sp == null) return defValue;
    return _sp!.get(key) ?? defValue;
  }

  ///有该key
  static bool haveKey(String key) {
    if (_sp == null) return false;
    return _sp!.getKeys().contains(key);
  }

  ///获取key列表
  static Set<String> getKeys() {
    if (_sp == null) return {};
    return _sp!.getKeys();
  }

  ///删除某个key的内容
  static Future<bool> remove(String key) {
    if (_sp == null) return Future.value(false);
    return _sp!.remove(key);
  }

  ///清除所有保存数据
  static Future<bool> clear() {
    if (_sp == null) return Future.value(false);
    return _sp!.clear();
  }
}
